#include <glib.h>

gint global_count = 0;
GRecMutex *global_rec_mutex = NULL;
GTimer *timer = NULL;
static gpointer _thread_func(gpointer data)
{
    gint i = 0;
    gpointer retval = NULL;

    g_rec_mutex_lock(global_rec_mutex);
    g_print("---sleep %d lock \n", GPOINTER_TO_INT(data));

    for(i=0;i<10000;i++) {
        global_count += i;
    }
    g_usleep(GPOINTER_TO_INT(data)*1000*1000);
    g_print("count:%d, elapsed:%f \n", global_count, g_timer_elapsed(timer, NULL));

    g_print("----sleep %d unlock \n", GPOINTER_TO_INT(data));

    g_print("before lock a recursion mutex \n");
    g_rec_mutex_lock(global_rec_mutex);
    g_rec_mutex_unlock(global_rec_mutex);
    g_print("after unlock a recursion mutex \n");

    g_rec_mutex_unlock(global_rec_mutex);

}

void test_thread_rec_mutex(void)
{
    GThread *th1,*th2,*th3;

    timer = g_timer_new();
    g_timer_start(timer);

    global_rec_mutex = g_new0(GRecMutex, 1);

    g_rec_mutex_init(global_rec_mutex);
    th1 = g_thread_new("th1", _thread_func, GINT_TO_POINTER(3));
    th2 = g_thread_new("th2", _thread_func, GINT_TO_POINTER(2));
    th3 = g_thread_new("th3", _thread_func, GINT_TO_POINTER(1));
    g_thread_join(th1);
    g_thread_join(th2);
    g_thread_join(th3);
    g_rec_mutex_clear(global_rec_mutex);
    g_free(global_rec_mutex);

    g_timer_destroy(timer);
}

gint main(gint argc, gchar **argv)
{
    g_test_init(&argc, &argv, NULL);

    g_test_add_func("/thread/rec_mutex", test_thread_rec_mutex);

    return g_test_run();
}